import { Cascader, Drawer, Form, Input, message, Radio, Select } from 'antd';
import Button from 'antd/es/button';
import { FormInstance, Rule } from 'antd/lib/form';
import FormItem from 'antd/lib/form/FormItem';
import React from 'react';
import { OrganizationInfo } from 'admin/schema/Organization';
import { SeatInfo } from 'admin/schema/Seat';
import {
  clearNull,
  encryptStr,
  verifyAccount,
  verifyAccountPwd,
  verifyNull,
  verifyPhone,
  verifySeatsNumber,
} from 'utils/tools';

import { addSeat, getOrganization, getSysUserInfo, modifySeat } from '../../../../servers/servers';
import '../style.scss';
import { verifyIdCard } from 'utils/tools';

interface UserOperationProps {
  /**提交函数结束后的回调,编辑需要传obj，判断是否跳第一页 */
  callback: (obj?: any) => any;
}

interface UserOperationState extends UserOperationProps {
  /**抽屉是否弹出 */
  visible: boolean;
  /** 打开用途（新建/编辑） */
  mode: 'create' | 'modify';
  /**组织结构树 */
  organizationData?: OrganizationInfo[];
  /** 用户组织 */
  organizationDefault: number[] | number;
  /**
   * 场景：
   * 有用户a，b，两个用户共享了用户表的数据权限，但是没有共享组织机构的数据权限，a用户去操作b用户创建的记录时，由于a拿不到b用户的组织机构数据，就会有问题
   * 当没有这个组织机构权限时，展示不可编辑的select控件
   */
  hasOrganizationData: boolean;
  /**
   * 不可编辑的select项
   */
  organizationItem: { label: string; value: number }[];
}

export class SeatOperation extends React.Component<UserOperationProps, UserOperationState> {
  /** 表单引用 */
  private formRef: React.RefObject<FormInstance>;

  /** 用户信息 */
  private seatInfo: SeatInfo;

  private isAdmin: boolean;

  constructor(prop: UserOperationProps) {
    super(prop);
    this.formRef = React.createRef();
    this.seatInfo = {} as SeatInfo;
    this.isAdmin = false;
    this.state = {
      ...prop,
      visible: false,
      mode: 'create',
      organizationData: [],
      organizationDefault: [],
      hasOrganizationData: true,
      organizationItem: [{ label: '', value: 0 }],
    };
  }

  componentDidMount() {
    getOrganization()
      .then(res => {
        this.setState({
          organizationData: res.data as any,
        });
      })
      .catch(error => {
        console.error(`系统异常: ${JSON.stringify(error)}`);
      });
  }

  /**
   * 获得登录用户信息
   */
  private determineIsAdmin(): void {
    getSysUserInfo()
      .then(res => {
        this.isAdmin = res.data.companyId === 0;
        if (this.isAdmin) {
          // 管理员账号
          this.setState(
            {
              hasOrganizationData: false,
              organizationItem: [
                {
                  value: 0,
                  label: '高阳捷讯外呼平台',
                },
              ],
              organizationDefault: 0,
            },
            () => {
              this.formRef.current?.setFieldsValue({
                organizationId: 0,
              });
            }
          );
        }
      })
      .catch(error => {
        console.error(`系统异常: ${JSON.stringify(error)}`);
      });
  }

  /**
   * 提交（新建/编辑）的数据
   */
  private submitData() {
    const form = this.formRef.current;
    form?.validateFields().then(res => {
      const val = form.getFieldsValue();
      const seatsNumber = val.seatsNumber.trim();
      const organizationId = this.isAdmin
        ? val.organizationId
        : val.organizationId[val.organizationId.length - 1];

      if (this.state.mode === 'create') {
        addSeat(
          clearNull({
            userName: val.userName,
            passWord: encryptStr(val.password),
            nickName: val.nickName,
            sex: val.sex,
            organizationId: organizationId,
            mobile: val.mobile,
            idCardNumber: encryptStr(val.idCardNumber),
            email: val.email,
            seatsNumber: seatsNumber,
          })
        )
          .then(res => {
            message.success('新增成功');
            this.close();
            this.state.callback();
          })
          .catch(error => {
            console.error(`系统异常: ${JSON.stringify(error)}`);
          });
      } else {
        modifySeat(
          this.seatInfo.userId as number,
          clearNull({
            userName: val.userName,
            nickName: val.nickName,
            sex: val.sex,
            organizationId: organizationId,
            mobile: val.mobile,
            idCardNumber: encryptStr(val.idCardNumber),
            email: val.email,
            seatsNumber: seatsNumber,
          })
        )
          .then(res => {
            message.success('编辑成功');
            this.close();
            this.state.callback(this.seatInfo.userId);
          })
          .catch(error => {
            console.error(`系统异常: ${JSON.stringify(error)}`);
          });
      }
    });
  }

  /**
   * 以新建/编辑的模式打开抽屉
   */
  public open(mode: 'create' | 'modify', initData?: SeatInfo) {
    if (!initData) {
      // initData为空时
      this.setState({
        visible: true,
        mode: mode,
      });
      this.determineIsAdmin();
      return;
    }
    const data = JSON.parse(JSON.stringify(initData)) as SeatInfo;
    this.seatInfo = data;
    getOrganization()
      .then(res => {
        const isAdmin = this.isAdmin;
        const arr: any[] = [];
        const deepFind = (item: OrganizationInfo) => {
          arr.push({
            id: item.organizationId,
            name: item.organizationName,
            idParent: item.idParent !== -1 ? item.idParent : null,
          });
          if (item.subOrganizations) {
            item.subOrganizations.forEach(son => {
              deepFind(son);
            });
          }
        };
        const defaultVal: number[] = [];
        const find = (target: any) => {
          defaultVal.push(target.id);
          if (target.idParent !== null) {
            const aim = arr.find(item => item.id === target.idParent);
            aim && find(aim);
          }
        };
        res.data.forEach(item => {
          deepFind(item);
        });
        const aim = arr.find(item => item.id === data.organizationId);
        // 不存在此项则说明用户无权编辑此项数据的组织结构
        if (!aim) {
          this.setState(
            {
              visible: true,
              mode: mode,
              hasOrganizationData: false,
              organizationItem: [
                {
                  value: data.organizationId as number,
                  label: data.organizationName as string,
                },
              ],
              organizationDefault: data.organizationId as number,
            },
            () => {
              delete data.organizationId;
              this.formRef.current?.setFieldsValue(data);
              this.forceUpdate();
            }
          );
          return;
        }
        find(aim);
        this.setState(
          {
            visible: true,
            mode: mode,
            organizationDefault: isAdmin ? 0 : defaultVal.reverse(),
          },
          () => {
            setTimeout(() => {
              delete data.organizationId;
              this.formRef.current?.setFieldsValue(data);
              this.determineIsAdmin();
            }, 0);
          }
        );
      })
      .catch(error => {
        console.error(`系统异常: ${JSON.stringify(error)}`);
      });
  }

  /**
   * 关闭抽屉
   */
  public close() {
    const isAdmin = this.isAdmin;
    this.setState({
      visible: false,
      organizationDefault: isAdmin ? 0 : [],
      organizationItem: [],
      hasOrganizationData: true,
    });
    this.formRef.current?.resetFields();
  }

  private buildFooter() {
    return (
      <div className="drawer-footer-buttongroup">
        <Button
          type="primary"
          onClick={() => {
            this.submitData();
          }}
        >
          确定
        </Button>
        <Button
          onClick={() => {
            this.close();
          }}
        >
          取消
        </Button>
      </div>
    );
  }

  render() {
    const {
      visible,
      mode,
      organizationData,
      organizationDefault,
      hasOrganizationData,
      organizationItem,
    } = this.state;

    const layout = {
      labelCol: { span: 6 },
      wrapperCol: { span: 16 },
    };

    return (
      <>
        {visible && (
          <Drawer
            width={620}
            visible={true}
            className="user-operation-drawer"
            title={mode === 'create' ? '新建坐席' : '编辑坐席'}
            onClose={() => {
              this.close();
            }}
            footer={this.buildFooter()}
          >
            <Form {...layout} layout="horizontal" ref={this.formRef} initialValues={{ sex: 0 }}>
              <FormItem
                label="账号"
                name="userName"
                rules={getRules('userName')}
                getValueFromEvent={event => {
                  return event.target.value.replace(/\s+/g, '');
                }}
              >
                <Input maxLength={15} placeholder="请输入15位内字符" />
              </FormItem>
              {mode === 'create' && (
                <FormItem
                  label="密码"
                  name="password"
                  rules={getRules('password')}
                  validateFirst={true}
                  getValueFromEvent={event => {
                    // 圆点符号包含逗号，所以过滤逗号需单独处理
                    return event.target.value
                      .replace(/,+/g, '')
                      .replace(/[^a-zA-Z0-9~@#\$*%\^:;_.+-\/]+/g, '')
                      .slice(0, 30);
                  }}
                >
                  <Input
                    minLength={8}
                    maxLength={30}
                    placeholder="8位以上字符，需包含大写字母、小写字母、数字和特殊字符中的三类"
                  />
                </FormItem>
              )}
              <FormItem
                label="用户名"
                name="nickName"
                rules={getRules('nickName')}
                getValueFromEvent={event => {
                  return event.target.value.replace(/\s+/g, '');
                }}
              >
                <Input maxLength={15} placeholder="请输入15位内字符" />
              </FormItem>
              <FormItem label="性别" name="sex" rules={getRules('sex', '请选择性别')}>
                <Radio.Group>
                  <Radio value={0}>男</Radio>
                  <Radio value={1}>女</Radio>
                </Radio.Group>
              </FormItem>
              <FormItem
                label="组织架构"
                name="organizationId"
                rules={getRules('organizationId', '请选择')}
                initialValue={organizationDefault}
              >
                {hasOrganizationData ? (
                  <Cascader
                    fieldNames={{
                      label: 'organizationName',
                      value: 'organizationId',
                      children: 'subOrganizations',
                    }}
                    style={{ marginRight: '15px' }}
                    changeOnSelect
                    value={organizationDefault as number[]}
                    options={organizationData as any}
                    placeholder="请选择用户的组织机构"
                  />
                ) : (
                  <Select disabled={true} options={organizationItem}></Select>
                )}
              </FormItem>
              {/* {mode === 'create' && (  <> */}
              <FormItem
                label="手机号"
                name="mobile"
                rules={getRules('mobile')}
                validateFirst={true}
                getValueFromEvent={event => {
                  return event.target.value.replace(/[^0-9]+/g, '');
                }}
              >
                <Input maxLength={11} placeholder="请输入11位数字" />
              </FormItem>
              <FormItem
                label="身份证号码"
                name="idCardNumber"
                // rules={getRules('idCardNumber')}
                validateFirst={true}
                getValueFromEvent={event => {
                  // 只能输入英文xX、数字
                  return event.target.value.replace(/[^xX0-9]+/g, '').slice(0, 18);
                }}
              >
                <Input maxLength={18} placeholder="请输入身份证号码" />
              </FormItem>
              {/* </>
              )} */}
              <FormItem
                label="电子邮箱"
                name="email"
                rules={[{ type: 'email', message: '电子邮箱格式不正确' }]}
                getValueFromEvent={event => {
                  return event.target.value.replace(/\s+/g, '');
                }}
              >
                <Input maxLength={100} placeholder="请输入电子邮箱" />
              </FormItem>
              <FormItem
                label="坐席工号"
                name="seatsNumber"
                rules={getRules('seatsNumber')}
                validateFirst={true}
                getValueFromEvent={event => {
                  return event.target.value.replace(/[^0-9]+/g, '');
                }}
              >
                <Input minLength={6} maxLength={6} placeholder="请输入6位数字" />
              </FormItem>
            </Form>
          </Drawer>
        )}
      </>
    );
  }
}

const getRules = (key: string, message?: string): Rule[] => {
  const ruleMap = new Map()
    .set('userName', verifyAccount)
    .set('password', verifyAccountPwd)
    .set('nickName', verifyNull(message))
    .set('sex', verifyNull(message))
    .set('roleId', verifyNull(message))
    .set('organizationId', verifyNull(message))
    .set('mobile', verifyPhone)
    .set('idCardNumber', verifyIdCard)
    .set('seatsNumber', verifySeatsNumber);

  return ruleMap.get(key);
};
